home *** CD-ROM | disk | FTP | other *** search
/ Amiga Collections: Taifun / Taifun 135 (1990-05-15)(Ossowski, Stefan)(DE)(PD)[v Disaster Master 2].zip / Taifun 135 (1990-05-15)(Ossowski, Stefan)(DE)(PD)[v Disaster Master 2].adf / MiscUtils / MusicGag.c < prev    next >
C/C++ Source or Header  |  1990-02-23  |  9KB  |  294 lines

  1. /*====================================================*/
  2. /*                                                                                                        */
  3. /* Sound a beep every time a key is pressed        V1.0        */
  4. /* © J.Tyberghein                                                                            */
  5. /*        Tue Sep 26 10:16:00 1989 V1.0                                        */
  6. /*        Tue Dec 19 12:07:19 1989                                                */
  7. /*                                                                                                        */
  8. /* compile with: (Lattice 5.0x)                                                */
  9. /*        lc -v -cms -O -j104 MusicGag                                        */
  10. /*        blink MusicGag.o lib lib:lc.lib                                    */
  11. /*                (no startupcode)                                                        */
  12. /*                                                                                                        */
  13. /*====================================================*/
  14.  
  15.  
  16. #include <exec/types.h>
  17. #include <exec/memory.h>
  18. #include <exec/interrupts.h>
  19. #include <devices/audio.h>
  20. #include <devices/input.h>
  21. #include <devices/inputevent.h>
  22. #include <proto/exec.h>
  23. #include <string.h>
  24.  
  25. #define VERSION                10
  26.  
  27. #define ERR_ALLOC            0
  28. #define ERR_OPEN            1
  29. #define ERR_CREATE        2
  30.  
  31. #define LEFT0F                1
  32. #define RIGHT0F                2
  33. #define RIGHT1F                4
  34. #define LEFT1F                8
  35.  
  36. #define ESCAPEKEY            0x45
  37.  
  38. #define SBUFLEN                2048L                    /* Sound buf length */
  39.  
  40. #pragma syscall AllocMem c6 1002
  41. #pragma syscall FreeMem d2 902
  42. #pragma syscall CloseLibrary 19e 901
  43. #pragma syscall OpenDevice 1bc 190804
  44. #pragma syscall CloseDevice 1c2 901
  45. #pragma syscall CheckIO 1d4 901
  46. #pragma syscall AbortIO 1e0 901
  47. #pragma syscall OpenLibrary 228 902
  48. #pragma syscall FindTask 126 901
  49. #pragma syscall Wait 13e 1
  50.  
  51. #pragma libcall Device BeginIO 1e 901
  52.  
  53. /*================================ Data ======================================*/
  54.  
  55. APTR DOSBase;
  56. #pragma libcall DOSBase Exit 90 101
  57.  
  58. /* Look for a left channel, then a right */
  59. UBYTE AllocationMap[] = { LEFT0F,LEFT1F,RIGHT0F,RIGHT1F };
  60.  
  61. UBYTE *SoundBuf = NULL;                    /* WaveForm Buffer */
  62. struct IOAudio *id1 = NULL;
  63. struct IOAudio *id2 = NULL;
  64. struct IOAudio *id3 = NULL;
  65. struct IOAudio *id4 = NULL;            /* Sound IDs */
  66.  
  67. typedef struct
  68.     {
  69.         struct Task *TaskToSig;
  70.         ULONG QuitSig,QuitSigNum,ActionSig,ActionSigNum;
  71.         LONG Rate;
  72.     } GlobalDat;
  73.  
  74. GlobalDat Global;
  75.  
  76. struct MsgPort *InputDevPort = NULL;
  77. struct IOStdReq *InputRequestBlock = NULL;
  78.  
  79. const char *PortName = "Sound Port";
  80.  
  81. struct InputEvent * __saveds __asm MyHandler
  82.         (register __a0 struct InputEvent *,register __a1 GlobalDat *);
  83. struct IOAudio *PlaySound (struct IOAudio *,UBYTE *,ULONG,WORD,WORD,WORD);
  84. void SetIOA (WORD,WORD,WORD,ULONG,struct IOAudio **);
  85. void CloseStuff (WORD);
  86.  
  87. /*================================ Code ======================================*/
  88.  
  89. /*---------------------------- Main program ----------------------------------*/
  90.  
  91. LONG __saveds myMain ()
  92. {
  93.     WORD i,Count,Div;
  94.     ULONG sig;
  95.     struct Interrupt HandlerStuff;
  96.     LONG Rate;
  97.     struct IOAudio *id;
  98.  
  99.     if (!(DOSBase = (APTR)OpenLibrary ("dos.library",0L))) return (100L);
  100.  
  101.     if (!(SoundBuf = (UBYTE *)AllocMem (SBUFLEN,MEMF_CHIP | MEMF_CLEAR)))
  102.         CloseStuff (ERR_ALLOC);
  103.  
  104.     Div = SBUFLEN/125;
  105.     for (i=0 ; i<SBUFLEN ; i++) SoundBuf[i] = (i%2) ? 127 : 127+(i-SBUFLEN)/Div;
  106.     SetIOA ((WORD)(3579545L/4000),64,1,SBUFLEN,&id1);
  107.     SetIOA ((WORD)(3579545L/4000),64,1,SBUFLEN,&id2);
  108.     SetIOA ((WORD)(3579545L/4000),64,1,SBUFLEN,&id3);
  109.     SetIOA ((WORD)(3579545L/4000),64,1,SBUFLEN,&id4);
  110.  
  111.     Global.QuitSigNum = Global.ActionSigNum = 0L;
  112.     Global.TaskToSig = FindTask (0L);
  113.     if (!(InputDevPort = CreatePort (0L,0L))) CloseStuff (ERR_CREATE);
  114.     if (!(InputRequestBlock = CreateStdIO (InputDevPort))) CloseStuff (ERR_CREATE);
  115.     if ((Global.QuitSigNum = AllocSignal (-1L)) == -1L) CloseStuff (ERR_ALLOC);
  116.     Global.QuitSig = 1L<<Global.QuitSigNum;
  117.     if ((Global.ActionSigNum = AllocSignal (-1L)) == -1L) CloseStuff (ERR_ALLOC);
  118.     Global.ActionSig = 1L<<Global.ActionSigNum;
  119.     HandlerStuff.is_Data = (APTR)&Global;
  120.     HandlerStuff.is_Code = (VOID (*)())MyHandler;
  121.     HandlerStuff.is_Node.ln_Pri = 52;
  122.     if (OpenDevice ("input.device",0L,(struct IORequest *)InputRequestBlock,0L))
  123.         CloseStuff (ERR_OPEN);
  124.     InputRequestBlock->io_Command = IND_ADDHANDLER;
  125.     InputRequestBlock->io_Data = (APTR)&HandlerStuff;
  126.     DoIO ((struct IORequest *)InputRequestBlock);
  127.     Count = 0;
  128.     for (;;)
  129.         {
  130.             sig = Wait (Global.QuitSig | Global.ActionSig);
  131.             if (sig & Global.QuitSig) break;
  132.             if (sig & Global.ActionSig)
  133.                 {
  134.                     switch (++Count)
  135.                         {
  136.                             case 0 : id = id1; break;
  137.                             case 1 : id = id2; break;
  138.                             case 2 : id = id3; break;
  139.                             case 3 : id = id4; Count = -1; break;
  140.                         }
  141.                     Rate = Global.Rate*150+200;
  142.                     AbortIO ((struct IORequest *)id);
  143.                     id = PlaySound (id,SoundBuf,SBUFLEN,1,(WORD)(3579545L/Rate),64);
  144.                 }
  145.         }
  146.     InputRequestBlock->io_Command = IND_REMHANDLER;
  147.     InputRequestBlock->io_Data = (APTR)&HandlerStuff;
  148.     DoIO ((struct IORequest *)InputRequestBlock);
  149.  
  150.     AbortIO ((struct IORequest *)id1);
  151.     AbortIO ((struct IORequest *)id2);
  152.     AbortIO ((struct IORequest *)id3);
  153.     AbortIO ((struct IORequest *)id4);
  154.     CloseStuff (0);
  155. }
  156.  
  157. /*------------------------- Input event handler ------------------------------*/
  158.  
  159. struct InputEvent * __saveds __asm MyHandler
  160.         (register __a0 struct InputEvent *ev,register __a1 GlobalDat *gdptr)
  161. {
  162.     register struct InputEvent *ep;
  163.  
  164.     for (ep=ev ; ep ; ep=ep->ie_NextEvent)
  165.         if (ep->ie_Class == IECLASS_RAWKEY)
  166.             if ((ep->ie_Code == ESCAPEKEY) && (ep->ie_Qualifier&IEQUALIFIER_RCOMMAND))
  167.                 {
  168.                     ep->ie_Class = IECLASS_NULL;
  169.                     Signal (gdptr->TaskToSig,gdptr->QuitSig);
  170.                 }
  171.             else if (ep->ie_Code<128)
  172.                 {
  173.                     gdptr->Rate = ep->ie_Code;
  174.                     Signal (gdptr->TaskToSig,gdptr->ActionSig);
  175.                 }
  176.     return (ev);
  177. }
  178.  
  179. /*-------------------------- Close everything --------------------------------*/
  180.  
  181. void CloseStuff (WORD Error)
  182. {
  183.     if (InputRequestBlock)
  184.         {
  185.             CloseDevice ((struct IORequest *)InputRequestBlock);
  186.             DeleteStdIO (InputRequestBlock);
  187.         }
  188.     if (Global.ActionSigNum) FreeSignal (Global.ActionSigNum);
  189.     if (Global.QuitSigNum) FreeSignal (Global.QuitSigNum);
  190.     if (InputDevPort) DeletePort (InputDevPort);
  191.     if (id1)
  192.         {
  193.             if (id1->ioa_Request.io_Device) CloseDevice ((struct IORequest *)id1);
  194.             if (id1->ioa_Request.io_Message.mn_ReplyPort)
  195.                 DeletePort (id1->ioa_Request.io_Message.mn_ReplyPort);
  196.             FreeMem (id1,(LONG)sizeof (struct IOAudio));
  197.         }
  198.     if (id2)
  199.         {
  200.             if (id2->ioa_Request.io_Device) CloseDevice ((struct IORequest *)id2);
  201.             if (id2->ioa_Request.io_Message.mn_ReplyPort)
  202.                 DeletePort (id2->ioa_Request.io_Message.mn_ReplyPort);
  203.             FreeMem (id2,(LONG)sizeof (struct IOAudio));
  204.         }
  205.     if (id3)
  206.         {
  207.             if (id3->ioa_Request.io_Device) CloseDevice ((struct IORequest *)id3);
  208.             if (id3->ioa_Request.io_Message.mn_ReplyPort)
  209.                 DeletePort (id3->ioa_Request.io_Message.mn_ReplyPort);
  210.             FreeMem (id3,(LONG)sizeof (struct IOAudio));
  211.         }
  212.     if (id4)
  213.         {
  214.             if (id4->ioa_Request.io_Device) CloseDevice ((struct IORequest *)id4);
  215.             if (id4->ioa_Request.io_Message.mn_ReplyPort)
  216.                 DeletePort (id4->ioa_Request.io_Message.mn_ReplyPort);
  217.             FreeMem (id4,(LONG)sizeof (struct IOAudio));
  218.         }
  219.     if (SoundBuf) FreeMem (SoundBuf,SBUFLEN);
  220.     CloseLibrary ((struct Library *)DOSBase);
  221.     Exit ((LONG)Error);
  222. }
  223.  
  224. /*---------------- Allocate and init an IO Request Block ---------------------*/
  225.  
  226. void SetIOA (WORD Per,WORD Vol,WORD Repeat,ULONG Len,struct IOAudio **ioa)
  227. {
  228.     struct MsgPort *Port;
  229.  
  230.     if (!(*ioa = (struct IOAudio *)AllocMem ((LONG)sizeof (struct IOAudio),
  231.                                 MEMF_PUBLIC | MEMF_CLEAR))) CloseStuff (ERR_ALLOC);
  232.     (*ioa)->ioa_Request.io_Message.mn_Node.ln_Pri = 10;
  233.     if (!(Port = CreatePort (PortName,0L)))
  234.         {
  235.             FreeMem (*ioa,(LONG)sizeof (struct IOAudio));
  236.             CloseStuff (ERR_CREATE);
  237.         }
  238.     else
  239.         {
  240.             /* Get a channel */
  241.             (*ioa)->ioa_Request.io_Message.mn_ReplyPort = Port;
  242.             (*ioa)->ioa_Data = AllocationMap;
  243.             (*ioa)->ioa_Length = sizeof (AllocationMap);
  244.             if (OpenDevice (AUDIONAME,0L,(struct IORequest *)*ioa,0L))
  245.                 {
  246.                     (*ioa)->ioa_Request.io_Device = NULL;
  247.                     CloseStuff (ERR_OPEN);
  248.                 }
  249.             else
  250.                 {
  251.                     /* Set Up Request */
  252.                     (*ioa)->ioa_Request.io_Flags = ADIOF_PERVOL;
  253.                     (*ioa)->ioa_Request.io_Command = CMD_WRITE;
  254.                     (*ioa)->ioa_Period = Per;
  255.                     (*ioa)->ioa_Volume = Vol;
  256.                     (*ioa)->ioa_Cycles = Repeat;
  257.                 }
  258.         }
  259. }
  260.  
  261. /*------------------------------ SetLength -----------------------------------*/
  262.  
  263. void SetLength (ULONG BufLen,UBYTE **DataHndl,struct IOAudio *ioa)
  264. {
  265.     ioa->ioa_Length = BufLen;
  266.     ioa->ioa_Data=(*DataHndl);
  267. }    
  268.  
  269. /*---------------------------- Play a sound ----------------------------------*/
  270.  
  271. struct IOAudio *PlaySound (struct IOAudio *ioa,UBYTE *Buffer,ULONG BufLen,
  272.                                                     WORD Repeat,WORD Period,WORD Volume)
  273. {
  274.     UBYTE *DataPtr;
  275.     WORD Count;
  276.     struct Device *Device;
  277.  
  278.     Count = Repeat ? (Repeat-1) : -1;
  279.     DataPtr = Buffer;
  280.     ioa->ioa_Request.io_Flags = ADIOF_PERVOL;
  281.     ioa->ioa_Request.io_Command = CMD_WRITE;
  282.     ioa->ioa_Period = Period;
  283.     ioa->ioa_Volume = Volume;
  284.     ioa->ioa_Cycles = Repeat;
  285.     SetLength (BufLen,&DataPtr,ioa);
  286.     /* Send command to Audio chip */
  287.     Device = ioa->ioa_Request.io_Device;
  288.     BeginIO ((struct IORequest *)ioa);
  289.     /* If no data remains to play, return ioa pointer */
  290.     return (ioa);
  291. }
  292.  
  293. /*=============================== The end ====================================*/
  294.